import socket
import time
import threading
import os


def recv_all(sock, bufsize):
    if sock is None:
        return None
    # 接收数据
    data = b""
    while True:
        part = sock.recv(bufsize)
        data += part
        if len(part) < bufsize:
            break
    return data


class SocketClient:
    def __init__(self, host, port):
        # 创建socket对象
        self.host = host
        self.port = port
        self.socket = None
        
    def __del__(self):
        # 关闭连接
        try:
            if self.socket is not None:
                self.socket.shutdown(socket.SHUT_RDWR)
                self.socket.close()
            print("client deconstructor")
        except Exception as e:
            print(e)
    
    def create_connection(self):
        if self.socket is not None:
            self.socket.close()
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        while True:
            try:
                # 连接到服务器
                self.socket.connect((self.host, self.port))
                print(f"Successfully connected to server on {self.host}:{self.port}")
                return True
            except Exception as e:
                print(e)
                time.sleep(1)
    
    def send(self, message):
        if self.socket is None:
            self.create_connection()
        try:
            # 向服务器发送数据
            self.socket.sendall(message.encode("utf-8"))
            return True
        except Exception as e:
            print(e)
            self.socket.close()
            self.socket = None
            return False

    def recv(self, bufsize=1024):
        if self.socket is None:
            self.create_connection()
        # 接收服务器返回的数据
        try:
            data = recv_all(self.socket, 1024)
            if data:
                res = data.decode('utf-8')
                print(f"从服务器收到的数据: {res}")
                return res
        except Exception as e:
            print(e)
            self.socket.close()
            self.socket = None
            return None


class SocketServer:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        # 创建socket对象
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setblocking(False)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.client_socket = None
        self.client_address = None
        
    def __del__(self):
        try:
            if self.client_socket is not None:
                self.client_socket.shutdown(socket.SHUT_RDWR)
                self.client_socket.close()
            self.server_socket.shutdown(socket.SHUT_RDWR)
            self.server_socket.close()
            print("server deconstructor")
        except Exception as e:
            print(e)
    
    def start(self):
        # 绑定IP地址和端口
        server_address = (self.host, self.port)
        self.server_socket.bind(server_address)
        # listen()函数的作用是将套接字设置为监听模式，服务器套接字将进入等待接收连接的状态。
        # 当有新的连接请求时，如果队列已满，服务器将拒绝连接；
        # 否则，服务器将创建一个新的套接字专门用于处理该连接请求，并将该套接字返回给客户端。
        # backlog:指定等待连接队列的最大请求数
        self.server_socket.listen(1)
    
    def accept_client(self) -> bool:
        # 关闭连接
        if self.client_socket is not None:
            self.client_socket.shutdown(socket.SHUT_RDWR)
            self.client_socket.close()
            self.client_socket = None
        print("accepting...")
        # 接受客户端连接
        try:
            self.client_socket, self.client_address = self.server_socket.accept()
            self.client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            print(f"Successfully connected to client on {self.host}:{self.port}")
            return True
        except Exception as e:
            print(e)
            return False
    
    def spin(self):
        while not self.accept_client():
            print("wait for client connection...")
            time.sleep(1)
    
    def send(self, message):
        if self.client_socket is None:
            self.spin()
        try:
            # 向客户端发送数据
            self.client_socket.sendall(message.encode("utf-8"))          
            return True
        except BrokenPipeError:
            # 发送数据时发生BrokenPipeError，说明接收端已经断开连接
            self.client_socket.close()
            self.client_socket = None
            return False
        except Exception as e:
            print(e)
            return False
            
    def recv(self):
        if self.client_socket is None:
            self.spin()
        # 接收客户端发送的数据
        try:
            data = recv_all(self.client_socket, 1024)
            if data:
                res = data.decode('utf-8')
                print(f"从客户端收到的数据: {res}")
                return res
        except socket.error as e:
            print(e)
            self.client_socket.close()
            self.client_socket = None
            return None
        

if __name__ == "__main__":
    socket_ip = os.getenv('SOCKET_IP', '127.0.0.1')
    socket_port = int(os.getenv('SOCKET_PORT', '10086'))
    # 创建SocketServer对象
    server = SocketServer(socket_ip, socket_port)
    server_thread = threading.Thread(target=server.accept_client)
    server_thread.start()
    # 创建SocketClient对象
    client = SocketClient(socket_ip, socket_port)
    # 发送数据
    client.send("Hello, server!")
    server.recv()
    server_thread.join()
